#include "watershedsegmentation.h"
#include <QDebug>
#include <vector>
WatershedSegmentation::WatershedSegmentation(QObject *parent):QObject(parent) {}

cv::Mat WatershedSegmentation::GetSegmentationImage(cv::Mat image)
{
    using namespace cv;
    // Mat src = imread(filePath);//输入原图
    Mat src = image.clone();
    // if(src.empty()){
    //     //
    //     qDebug()<<"图像为空";
    //     return nullptr;
    // }
    //图像灰度化
    Mat gray;
    cvtColor(src,gray,COLOR_BGR2GRAY);
    //图像二值化
    Mat binary;
    threshold(gray,binary,0,255,THRESH_BINARY|cv::THRESH_OTSU);
    // imshow("binary",binary);
    qDebug()<<"binary....";
    //执行距离变换
    Mat dist;
    distanceTransform(binary,dist,DistanceTypes::DIST_L2,3,CV_32F);
    qDebug()<<"distanceTransform....";
    normalize(dist,dist,0.0,1.0,NORM_MINMAX);//归一化0~1之间
    qDebug()<<"normalize....";
    //重新二值化预值
    threshold(dist,dist,0.1,1.0,THRESH_BINARY);
    qDebug()<<"threshold....";
    normalize(dist,dist,0,255,NORM_MINMAX);
    qDebug()<<"normalize....";
    dist.convertTo(dist,CV_8UC1);//
    qDebug()<<"convertTo....";

    //开始生成marker并绘制出来
    std::vector<std::vector<Point>> contours;
    std::vector<Vec4i> heri;
    findContours(dist,contours,RETR_CCOMP,CHAIN_APPROX_SIMPLE);
    qDebug()<<"findContours....";

    Mat marker = Mat::zeros(dist.size(),CV_32S);
    for(size_t i = 0;i<contours.size();i++){
        drawContours(marker,contours,i,Scalar(i+1),-1, 8, heri, INT_MAX);
    }
    qDebug()<<"drawContours...."<<contours.size();
    circle(marker, Point(5, 5), 3, Scalar(255), -1);
    watershed(src,marker);
    qDebug()<<"watershed....";
    // marker.convertTo(marker,CV_8UC1);//ps:此处需要注意（到这里实际上已经完成了算法）。一旦不转换就不能用imshow，一旦转换了后面的marker着色就会出现异常
       // imshow("marker",marker);
    // return marker;
    // qDebug()<<"imshow(marker,marker);....";
    // //生成颜色数组
    std::vector<Vec3b> colors;
    for (size_t i = 0; i < contours.size(); i++) {
        int r = theRNG().uniform(0, 255);
        int g = theRNG().uniform(0, 255);
        int b = theRNG().uniform(0, 255);
        colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
    }

    // //给marker着色
    Mat finalResult = Mat::zeros(dist.size(),CV_8UC3);//三通道彩色图像
    int index = 0;
    for(int row = 0;row<marker.rows;row++){
        for(int col = 0;col<marker.cols;col++){
            index = marker.at<int>(row,col);
            if(index>0&&index<=contours.size()){
                finalResult.at<Vec3b>(row,col)  = colors[index-1];
            }else{
                finalResult.at<Vec3b>(row,col) = Vec3b(255,255,255);
            }
        }
    }
    imshow("finalResult",finalResult);
    return finalResult;
}
